gusucode.com > VC++ RingSDK界面库 > VC++ RingSDK界面库/code/libsrc/ringdib/rdib.cpp
/********************************************************************** // // // ########## ###### ######### # ###### # // ############# ########### ######### ######### ### // ######## # ### ## ############# ## ## ##### # #### // #### ## ## ### ### ### # # ##### ##### // # ### # # ## ## ## ## ### // ## ###### ## ## #### #### # # ## // ######### ### ## ### ####### ###### ## ## ### // ###### ## ###### ## ## #### # ## #### // ####### ## ###### ## ### ## ## ### ###### // ######### ## ###### ## ###### ### ## ### # ##### // ## ###### ####### ### #### ## ## ####### ######## ## #### // ## #### ### # ### ### ## ########## ###### ## #### // ## ## ## ######### #### # ## // # ### // ## // ### // ## // // // RingSDK多媒体类库 ringdib.lib //作者:临风 // //版本:1.0 // //声明:本类库可以自由使用而不须对作者作出任何回报,但作者希望能得到 // 你的鼓励和支持。你可以对类库源码作出修改和改进,但希望你能在 // 修改的同时给作者一份同样的副本。 // 本类库不得用于任何商业用途,如确实需要,请与作者联系。 // //e-mail:ringphone@sina.com // //原文件名:rdib.cpp // //说明:图象载入部分RingDIB类实现代码 // **********************************************************************/ #define MAKE_SELF_LIB #include "ringdib.h" #define MAX_PIC_FORMAT 20 //最多支持文件格式(外挂图象解码支持) static struct stdibext{ char ext[8]; stdibext(){memset(ext,0,8);} }dib_load_ext[MAX_PIC_FORMAT]; static struct stdibfunc{ DECODER_FUNC ext_func; stdibfunc(){ext_func=NULL;} }dib_load_funcs[MAX_PIC_FORMAT]; //滤镜插件类纯虚析构函数体 DibFilter::~DibFilter() { } int RingDIB::pluged_ext = 0; HDRAWDIB RingDIB::m_hDrawDib = NULL; RingDIB* RingDIB::m_dibCanvas = NULL; LONG RingDIB::m_nObjCount = 0; RingDataGuard RingDIB::m_guard; RingDIB::RingDIB() { init(); } RingDIB::RingDIB(HWND hWnd) { init(); if(IsWindow(hWnd)) m_hWnd = hWnd; } void RingDIB::init() { m_bmif.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); m_bmif.bmiHeader.biWidth = 0; m_bmif.bmiHeader.biHeight = 0; m_bmif.bmiHeader.biPlanes = 1; m_bmif.bmiHeader.biBitCount = 32; m_bmif.bmiHeader.biCompression = BI_RGB; m_bmif.bmiHeader.biClrImportant = 0; m_bmif.bmiHeader.biClrUsed = 0; m_bmif.bmiHeader.biSizeImage = 0; m_bmif.bmiHeader.biXPelsPerMeter = 0; m_bmif.bmiHeader.biYPelsPerMeter = 0; m_width=0; m_height=0; m_Bits=NULL; m_aniGifPic = NULL; m_lGifInfo = NULL; m_backup = m_actbak = m_target = NULL; m_crKey = 0xFFFFFFFF; m_hWnd = GetMainWnd(); m_hrgn = NULL; m_size = 0; SetRect(&m_rcSrc,0,0,0,0); SetRect(&m_rcDest,0,0,0,0); m_currFunc = NULL; pluged_filter = 0; ZeroMemory(&m_Filter,sizeof(DIBFILTERINFO)); dib_load_funcs[0].ext_func = LoadBmp; m_guard.Enter(); if(m_hDrawDib == NULL) m_hDrawDib = DrawDibOpen(); m_nObjCount ++; m_guard.Leave(); } LPLOCALGIFINFO RingDIB::GetLocalGifInfo() { if(m_lGifInfo == NULL) { m_lGifInfo = (LPLOCALGIFINFO)New(sizeof(LOCALGIFINFO)); if(m_lGifInfo) { m_lGifInfo->AniThread = NULL; m_lGifInfo->bNeedBak = FALSE; m_lGifInfo->bgC = 0; m_lGifInfo->bActive = FALSE; m_lGifInfo->funcFilter = NoneFilter; } } return m_lGifInfo; } RingDIB::~RingDIB() { Destroy(); NewSize(0); for(int i=0;i<pluged_filter;i++) { if(m_Filter.m_filter[i]!=NULL) { delete (LPDIBFILTER)m_Filter.m_filter[i]; m_Filter.m_filter[i] = NULL; } else break; } if(m_hrgn) { DeleteObject(m_hrgn); m_hrgn = NULL; } try { delete m_lGifInfo; delete m_actbak; delete m_backup; m_lGifInfo = NULL; m_actbak = m_backup = NULL; } catch(...) { } //析构:这里不能用m_guard.Enter(),因为如果是静态产生对象(RingDIB dibobjname;方式产生), //静态的m_guard有可能先于本对象析构。 LONG ncnt = InterlockedDecrement(&m_nObjCount); if(ncnt == 0) { //同样不能FreeCanvas();因该函数调用m_guard.Enter() delete m_dibCanvas; m_dibCanvas = NULL; DrawDibClose(m_hDrawDib); m_hDrawDib = NULL; } else if(ncnt < 0) { //FreeCanvas()会继续m_nObjCount-1,使m_nObjCount=-1 InterlockedIncrement(&m_nObjCount); } } void RingDIB::Destroy() //析构函数调用; { EnableAniGif(); if(m_lGifInfo) { delete m_lGifInfo->AniThread; m_lGifInfo->AniThread = NULL; m_lGifInfo->bNeedBak = FALSE; m_lGifInfo->bgC = 0; m_lGifInfo->bActive = FALSE; m_lGifInfo->funcFilter = NoneFilter; } if(m_aniGifPic) { //删除循环链表 LPANIGIFPIC mark,save,temp; mark = m_aniGifPic; m_aniGifPic = NULL; save = mark->next; while(save && save != mark) { Del(save->curr); temp=save; save = save->next; Del(temp); } Del(mark->curr); Del(mark); } } BOOL RingDIB::NewSize(int nNewsize) { if(nNewsize > 0) { if(nNewsize <= m_size) { RtlZeroMemory(m_Bits,nNewsize); return TRUE; } else { m_Bits = (COLORREF*)Del(m_Bits); m_Bits = (COLORREF*)New(nNewsize); if(m_Bits != NULL) { m_size = nNewsize; return TRUE; } else m_size = 0; } } else if(nNewsize == 0) { m_Bits = (COLORREF*)Del(m_Bits); m_size = 0; return TRUE; } return FALSE; } //注册图象解码程序 BOOL RingDIB::RegFormat(LPCSTR ext,DECODER_FUNC ext_func) { if(pluged_ext >= MAX_PIC_FORMAT) return FALSE; if(ext && *ext != '\0') { int extlen = strlen(ext); int max = extlen > 7?7:extlen; strncpy(dib_load_ext[pluged_ext].ext,ext,max); dib_load_ext[pluged_ext].ext[max] = '\0'; pluged_ext++; if(ext_func) { //dib_load_funcs[0]为LoadBmp for(int i=1;i<MAX_PIC_FORMAT;i++) { if(dib_load_funcs[i].ext_func == NULL) { dib_load_funcs[i].ext_func = ext_func; break; } else if(dib_load_funcs[i].ext_func == ext_func) break; } } return TRUE; } return FALSE; } //运行/停止GIF动画 void RingDIB::EnableAniGif(BOOL bActive) { if(m_aniGifPic && m_lGifInfo) if(m_lGifInfo->bActive && !bActive) { if(m_lGifInfo->AniThread) m_lGifInfo->AniThread->Pause(); m_lGifInfo->bActive = FALSE; } else if(!m_lGifInfo->bActive && bActive) { if(m_lGifInfo->AniThread) m_lGifInfo->AniThread->Resume(); m_lGifInfo->bActive = TRUE; } } BOOL RingDIB::Import(LPBYTE lpdata,int width,int height) { if(lpdata && Create(width,height)) { memcpy(m_Bits,lpdata,width * height * sizeof(COLORREF)); return TRUE; } return FALSE; } BOOL RingDIB::Select(BOOL bAllFile,HWND hWnd/*=m_hWnd*/,LPCTSTR dlgEx/*=NULL*/,LPOFNHOOKPROC hookproc/*=NULL*/) { ringFile rf; char str[200]; ZeroMemory(str,200); wsprintf(str,"图象文件\0"); int len = 9,extlen,j; str[len++] = '*'; str[len++] = '.'; str[len++] = 'b'; str[len++] = 'm'; str[len++] = 'p'; for(int i=0;i<pluged_ext;i++) { str[len++] = ';'; str[len++] = '*'; str[len++] = '.'; extlen = strlen(dib_load_ext[i].ext); for(j=0;j<extlen;j++) str[len++] = dib_load_ext[i].ext[j]; } if(bAllFile) { str[len++] = ';'; str[len++] = '*'; str[len++] = '.'; str[len++] = '*'; str[len++] = '\0'; str[len] = '\0'; } else { str[len++] = '\0'; str[len] = '\0'; } if(rf.Select(str,NULL,FALSE,hWnd,dlgEx,hookproc)) return Load(rf.Fullname()); else return FALSE; } LPSTR RingDIB::GetFormat(LPSTR lpszFormat) { if(m_currFunc && m_currFunc(NULL,this,DIB_GETFORMAT,lpszFormat)) return lpszFormat; else return NULL; } BOOL RingDIB::IsImage(LPSTR szPicFilename) { for(int i=0;i<pluged_ext;i++) { if(dib_load_funcs[i].ext_func && dib_load_funcs[i].ext_func(szPicFilename,this,DIB_QUERYSUPPORT,NULL)) return TRUE; } return FALSE; } BOOL RingDIB::Load(UINT uBmpId) { Destroy(); return LoadBmp(MAKEINTRESOURCE(uBmpId),this); } BOOL RingDIB::Load(LPCTSTR szPicFilename) { Destroy(); if(IS_INTRESOURCE(szPicFilename)) return LoadBmp(szPicFilename,this); else { for(int i=0;i<MAX_PIC_FORMAT;i++) { if(dib_load_funcs[i].ext_func) { if(dib_load_funcs[i].ext_func(szPicFilename,this,DIB_QUERYSUPPORT,NULL) && dib_load_funcs[i].ext_func(szPicFilename,this,DIB_LOADDIB,NULL)) { m_currFunc = dib_load_funcs[i].ext_func; return TRUE; } } else break; } } return FALSE; } BOOL RingDIB::Create(int width,int height) { Destroy(); if(NewSize(width*height*sizeof(COLORREF))) { m_width=width; m_height=height; SetSrc(0,0); SetDest(0,0); return TRUE; } else return FALSE; } void RingDIB::ClipRect(int& x,int& y,int& width,int& height) { int n; //绘制区域处理,限定在图象内部 if(width == 0) n = m_width; else n = min(m_width,x + width); x = max(0,x); width = max(0,n - x); if(height == 0) n = m_height; else n = min(m_height,y + height); y = max(0,y); height = max(0,n - y); } void RingDIB::SetSrc(int x,int y,int width,int height) { ClipRect(x,y,width,height); SetRect(&m_rcSrc,x,y,x + width,y + height); } void RingDIB::SetDest(int x,int y,int width,int height) { if(height == 0) height = m_height; else if(height < 0) height = 0; if(width == 0) width = m_width; else if(width < 0) width = 0; SetRect(&m_rcDest,x,y,x + width,y + height); } BOOL RingDIB::DIBDraw(HDC hDC,int dx,int dy,int dw,int dh,int sx,int sy,int sw,int sh,UINT wFlags) { m_bmif.bmiHeader.biWidth = m_width; m_bmif.bmiHeader.biHeight = m_height; return DrawDibDraw(m_hDrawDib,hDC,dx,dy,dw,dh,&(m_bmif.bmiHeader),m_Bits, sx,sy,sw,sh,wFlags); } //根据源,目的坐标绘制 BOOL RingDIB::Draw(HDC hDC,BOOL bStretch/*=TRUE*/,UINT wFlags/*=DDF_HALFTONE*/) { if(m_Bits) { int w,h; if(!bStretch) { w = m_rcSrc.right - m_rcSrc.left; h = m_rcSrc.bottom - m_rcSrc.top; } else { w = m_rcDest.right - m_rcDest.left; h = m_rcDest.bottom-m_rcDest.top; } return DIBDraw(hDC,m_rcDest.left,m_rcDest.top,w,h,m_rcSrc.left,m_rcSrc.top, m_rcSrc.right-m_rcSrc.left,m_rcSrc.bottom-m_rcSrc.top,wFlags); } return FALSE; } BOOL RingDIB::Draw(BOOL bStretch,UINT wFlags) { BOOL bOK = FALSE; if(m_Bits) { HDC hDC = GetDC(m_hWnd); bOK = Draw(hDC,bStretch,wFlags); ReleaseDC(m_hWnd,hDC); } return bOK; } //指定目标与源位置绘制 //目标与源的宽度不指定,则均采用源起始位置后的整个图象宽高 //指定目标宽高,则为拉伸绘制 BOOL RingDIB::Draw(HDC hDC,int dx,int dy,int sx,int sy,int dw,int dh,int sw,int sh,UINT wFlags) { if(m_Bits) { //源绘制区域处理,限定在图象内部 ClipRect(sx,sy,sw,sh); //目标绘制区域处理 if(dw == 0) dw = sw; if(dh == 0) dh = sh; return DIBDraw(hDC,dx,dy,dw,dh,sx,sy,sw,sh,wFlags); } return FALSE; } //指定目标与源位置绘制, BOOL RingDIB::Draw(int dx,int dy,int sx,int sy,int dw,int dh,int sw,int sh,UINT wFlags) { BOOL bOK = FALSE; if(m_Bits) { HDC hDC = GetDC(m_hWnd); bOK = Draw(hDC,dx,dy,sx,sy,dw,dh,sw,sh,wFlags); ReleaseDC(m_hWnd,hDC); } return bOK; } BOOL RingDIB::Paint(BOOL bStretch,UINT wFlags) { BOOL bOK = FALSE; if(m_Bits) { PAINTSTRUCT ps; BeginPaint(m_hWnd,&ps); bOK = Draw(ps.hdc,bStretch,wFlags); EndPaint(m_hWnd,&ps); } return bOK; } BOOL RingDIB::Paint(int dx,int dy,int sx,int sy,int dw,int dh,int sw,int sh,UINT wFlags) { BOOL bOK = FALSE; if(m_Bits) { PAINTSTRUCT ps; BeginPaint(m_hWnd,&ps); bOK = Draw(ps.hdc,dx,dy,sx,sy,dw,dh,sw,sh,wFlags); EndPaint(m_hWnd,&ps); } return bOK; } //数据COPY操作绘制,无拉伸,整个源图象数据复制(根据目标图象大小剪裁) BOOL RingDIB::DrawTo(RingDIB* Dest,int x,int y,BOOL bTrans) { return DrawTo(Dest,x,y,0,0,m_width,m_height,bTrans); } //数据COPY操作绘制,无拉伸 BOOL RingDIB::DrawTo(RingDIB* Dest,int dx,int dy,int sx,int sy,int w,int h,BOOL bTrans) { if(m_Bits && Dest && Dest->m_Bits) { ClipRect(sx,sy,w,h); if(w == 0 || h == 0) //源区域为空 return FALSE; Dest->ClipRect(dx,dy,w,h); if(w == 0 || h == 0) //目的区域为空 return FALSE; int i,j,a,t; COLORREF *Src,*Dst,*srcbak,*dstbak; //DIB图象数据上下颠倒,因此图象偏移量须上下颠倒计算 a = (m_height - (sy + h)) * m_width + sx; t = (Dest->m_height - (dy + h)) * Dest->m_width + dx; srcbak = Src = m_Bits + a; dstbak = Dst = Dest->m_Bits + t; if(m_crKey == 0xffffffff || !bTrans) //不透明 { for(j=0;j<h;j++) { for(i=0;i<w;i++) { *Dst++ = *Src++; } srcbak += m_width; dstbak += Dest->m_width; Src = srcbak; Dst = dstbak; } } else //透明 { for(j=0;j<h;j++) { for(i=0;i<w;i++) { if(*Src != m_crKey) *Dst = *Src; Src++;Dst++; } srcbak += m_width; dstbak += Dest->m_width; Src = srcbak; Dst = dstbak; } } return TRUE; } return FALSE; } BOOL RingDIB::DrawToCanvas(int x,int y,BOOL bTrans) { return DrawTo(m_dibCanvas,x,y,bTrans); } BOOL RingDIB::StretchTo(RingDIB* Dest,int dx,int dy,int dw,int dh, int sx,int sy,int sw,int sh) { if(m_Bits && Dest && Dest->m_Bits) { float fsw,fsh; int i,j,a,t; COLORREF *Src,*Dst,*srcbak,*dstbak,*lpsData,*lpdData; ClipRect(sx,sy,sw,sh); if(sw == 0 || sh == 0) //源区域为空 return FALSE; Dest->ClipRect(dx,dy,dw,dh); if(dw == 0 || dh == 0) //目的区域为空 return FALSE; fsw = (float)sw; fsh = (float)sh; //DIB图象数据上下颠倒,因此图象偏移量须上下颠倒计算 a = (m_height - (sy + sh)) * m_width + sx; t = (Dest->m_height - (dy + dh)) * Dest->m_width + dx; srcbak = Src = m_Bits + a; dstbak = Dst = Dest->m_Bits + t; float x = fsw/(float)dw; float y = fsh/(float)dh; float x_cnt,y_cnt=0.00; for(j=0;j<dh;j++) { x_cnt=0.00; for(i=0;i<dw;i++) { *lpdData++ = *lpsData; x_cnt += x; lpsData = Src + (int)x_cnt; } y_cnt += y; lpsData = Src = srcbak + m_width * (int)y_cnt; lpdData += Dest->m_width; } return TRUE; } return FALSE; } BOOL RingDIB::Fill(COLORREF crColor) { if(m_Bits) { int nSize = m_width*m_height; COLORREF* lpd = m_Bits; while(nSize-- > 0) *lpd++ = crColor; return TRUE; } else return FALSE; } BOOL RingDIB::Fill(BYTE r,BYTE g,BYTE b) { return Fill(RGB(r,g,b)); } BOOL RingDIB::FillRect(COLORREF crColor,int x,int y,int width,int height) { if(m_Bits) { int i,j,a; COLORREF *Src,*srcbak; ClipRect(x,y,width,height); if(width == 0 || height == 0) return FALSE; a = (m_height - (y + height)) * m_width + x; srcbak = Src = m_Bits + a; for(j=0;j<height;j++) { for(i=0;i<width;i++) { *Src++ = crColor; } srcbak += m_width; Src = srcbak; } return TRUE; } return FALSE; } //抓屏 BOOL RingDIB::Capture(HWND hwnd/*=NULL*/) { if(hwnd == NULL && m_width != WINVAR_DESKTOP_X && m_height != WINVAR_DESKTOP_Y) { Create(WINVAR_DESKTOP_X,WINVAR_DESKTOP_Y); hwnd = GetDesktopWindow(); } else Create(WinWidth(hwnd),WinHeight(hwnd)); HBITMAP hbm; HDC hDC = GetDC(hwnd); HDC hMemDC = CreateCompatibleDC(hDC); hbm = CreateCompatibleBitmap(hDC,m_width,m_height); SelectObject(hMemDC,hbm); BitBlt(hMemDC,0,0,m_width,m_height,hDC,0,0,SRCCOPY); m_bmif.bmiHeader.biWidth=m_width; m_bmif.bmiHeader.biHeight=m_height; GetDIBits(hDC,hbm,0,m_height,m_Bits,&m_bmif,DIB_RGB_COLORS); DeleteDC(hMemDC); ReleaseDC(hwnd,hDC); DeleteObject(hbm); return TRUE; } RingDIB* RingDIB::CreateCanvas(HWND hWnd,int width,int height) { if(hWnd == NULL) hWnd = m_hWnd; if(width == 0) width = m_width; if(height == 0) height = m_height; m_guard.Enter(); if(m_dibCanvas == NULL) { m_dibCanvas = new RingDIB(hWnd); //m_dibCanvas创建时也会将m_nObjCount+1,导致最后一个对象释放时m_nObjCount非0, //因此需--退回避免该情况,析构时m_nObjCount的处理在析构函数中判断 m_nObjCount --; if(m_dibCanvas) m_dibCanvas->Create(width,height); } else m_dibCanvas->SetTarget(hWnd); m_guard.Leave(); return m_dibCanvas; } void RingDIB::FreeCanvas() { m_guard.Enter(); delete m_dibCanvas; m_dibCanvas = NULL; m_guard.Leave(); } //备份图象数据 BOOL RingDIB::Backup() { return (BOOL)MakeCopy(m_backup); } BOOL RingDIB::Restore(BOOL bTrans) { if(m_backup) return m_backup->DrawTo(this,0,0,0,0,m_width,m_height,bTrans); else return FALSE; } //相同大小图象复制 BOOL RingDIB::CopyTo(RingDIB* Dest) { if(m_Bits && Dest && Dest->m_Bits && m_width == Dest->m_width && m_height == Dest->m_height) { memcpy(Dest->m_Bits,m_Bits,m_width*m_height*sizeof(COLORREF)); return TRUE; } else return FALSE; } //创建并复制图象,返回对象必须由调用者销毁 RingDIB* RingDIB::MakeCopy(RingDIB* Dest/*=NULL*/) { if(m_Bits) { if(Dest == NULL) Dest = new RingDIB(m_hWnd); if(Dest) { Dest->Create(m_width,m_height); if(CopyTo(Dest)) return Dest; } } return NULL; } //90度旋转图象,旋转后m_rcSrc为整个图象 BOOL RingDIB::Rotate(BYTE pos) { SetSrc(0,0); if(m_Bits) { m_actbak = MakeCopy(m_actbak); if(m_actbak == NULL) return FALSE; int skip = 4; LPBYTE lpData = (LPBYTE)m_actbak->m_Bits; int new_width = m_width * skip; LPBYTE lpDest; int width_plus,height_plus; switch(pos) { case DIB_LFPOS_UL: //图像向左旋转90度后上下反转 lpDest = (LPBYTE)m_Bits + new_width * m_height - skip; width_plus = -new_width-skip; height_plus = -skip; break; case DIB_LFPOS_DL: //图像向左旋转90度 lpDest = (LPBYTE)m_Bits + new_width - skip; width_plus = new_width - skip; height_plus = -skip; break; case DIB_LFPOS_DR: //图像向右旋转90度后上下反转 lpDest = (LPBYTE)m_Bits; width_plus = new_width-skip; height_plus = skip; break; case DIB_LFPOS_UR: //图像向右旋转90度 lpDest = (LPBYTE)m_Bits + new_width * (m_height - 1); width_plus = -new_width-skip; height_plus = skip; break; default: return FALSE; } LPBYTE lpBak = lpDest; //宽高已调换 for(int j=0;j<m_width;j++) { for(int i=0;i<m_height;i++) { for(int k=0;k<skip;k++) { *lpDest++ = *lpData++; } lpDest += width_plus; } lpBak += height_plus; lpDest = lpBak; } return TRUE; } return FALSE; } //反转绘制 BOOL RingDIB::Flip(BYTE pos) { if(m_Bits) { m_actbak = MakeCopy(m_actbak); if(m_actbak == NULL) return FALSE; int skip = 4; LPBYTE lpData; lpData = (LPBYTE)m_actbak->m_Bits; int width = m_width * skip; LPBYTE lpDest; int width_plus,height_plus; switch(pos) { case DIB_LFPOS_UL: //与原图像相同 //CopyMemory(Dest->Data(),Data(),Dest->Width() * Dest->Height() * skip); return TRUE; case DIB_LFPOS_DL: //图像上下反转 lpDest = (LPBYTE)m_Bits + width * (m_actbak->m_height - 1); width_plus=0; height_plus = -(width<<1); break; case DIB_LFPOS_DR: //图像旋转180度 lpDest = (LPBYTE)m_Bits + width * m_actbak->m_height - skip; width_plus = -(skip<<1); height_plus=0; break; case DIB_LFPOS_UR: //图像左右反转 lpDest = (LPBYTE)m_Bits + width - skip; width_plus = -(skip<<1); height_plus = width<<1; break; default: return FALSE; } for(int j=0;j<m_height;j++) { for(int i=0;i<m_width;i++) { for(int k=0;k<skip;k++) { *lpDest++ = *lpData++; } lpDest += width_plus; } lpDest += height_plus; } return TRUE; } return FALSE; } BOOL RingDIB::DrawText(LPCTSTR szText,int x,int y,COLORREF crText/* = 0xFFFFFFFF*/,ringFont* rFont/* = NULL*/,BOOL bAutoAdjust/*=TRUE*/) { if(szText && m_Bits) { HBITMAP hbm = GetBitmap(); HDC hDC = GetDC(m_hWnd); HDC hMemDC = CreateCompatibleDC(hDC); SelectObject(hMemDC,hbm); SetBkMode(hMemDC, TRANSPARENT); if(crText != 0xFFFFFFFF) SetTextColor(hMemDC,crText); if(rFont && rFont->GetFont()) if(bAutoAdjust && x < m_width && y < m_height) SelectObject(hMemDC,rFont->AutoAdjust(szText,m_width - x,m_height - y,hMemDC)); else SelectObject(hMemDC,rFont->GetFont()); TextOut(hMemDC,x,y,szText,strlen(szText)); DeleteObject(hMemDC); //DeleteObject(hbm); ReleaseDC(m_hWnd,hDC); Import(hbm); DeleteObject(hbm); return TRUE; } return FALSE; } BOOL RingDIB::DrawText(LPCTSTR szText,LPRECT lprc,UINT uFormat,COLORREF crText/* = 0xFFFFFFFF*/,ringFont* rFont/* = NULL*/) { if(szText && m_Bits) { HBITMAP hbm = GetBitmap(); HDC hDC = GetDC(m_hWnd); HDC hMemDC = CreateCompatibleDC(hDC); SelectObject(hMemDC,hbm); SetBkMode(hMemDC, TRANSPARENT); if(crText != 0xFFFFFFFF) SetTextColor(hMemDC,crText); if(rFont && rFont->GetFont()) SelectObject(hMemDC,rFont->GetFont()); ::DrawText(hMemDC,szText,strlen(szText),lprc,uFormat); DeleteObject(hMemDC); ReleaseDC(m_hWnd,hDC); Import(hbm); DeleteObject(hbm); return TRUE; } return FALSE; } HRGN RingDIB::CreateRgn(BOOL bForceNoneRect) { int i,j,k; COLORREF *lpb,*lpbBak; BOOL bFinded = FALSE; RECT rt; HRGN hrgnS; if(m_Bits) { if(m_hrgn) DeleteObject(m_hrgn); if(m_aniGifPic) { EnableAniGif(FALSE); MakeBkg(); } if(m_crKey == 0xffffffff && bForceNoneRect) m_crKey = m_Bits[m_width * (m_height - 1)]; lpb = lpbBak = m_Bits; for(j=0,k=m_height-1;j<m_height;j++,k--) { for(i=0;i<m_width;i++) { if(*lpb != m_crKey) { bFinded = TRUE; lpb++; i++; break; } lpb++; } if(bFinded) break; lpbBak += m_width; lpb = lpbBak; } m_hrgn = CreateRectRgn(i,k,i+1,k+1); for(;j<m_height;j++,k--) { rt.top = k; rt.bottom = k+1; rt.left = -1; rt.right = -1; while(i<m_width) { for(;i<m_width;i++) { if(*lpb != m_crKey) { rt.left = i; lpb ++; i++; break; } lpb ++; } for(;i<m_width;i++) { if(*lpb == m_crKey) { rt.right = i; lpb ++; i++; break; } lpb ++; } if(rt.left == -1) break; if(rt.right == -1) rt.right = m_width; hrgnS = CreateRectRgn(rt.left,rt.top,rt.right,rt.bottom); CombineRgn(m_hrgn,m_hrgn,hrgnS,RGN_OR); DeleteObject(hrgnS); rt.top = k; rt.bottom = k+1; rt.left = -1; rt.right = -1; } lpbBak += m_width; lpb = lpbBak; i = 0; } if(m_aniGifPic) EnableAniGif(); return m_hrgn; } return NULL; } HRGN RingDIB::CreateCoolWindow(BOOL bForceNoneRect) { CreateRgn(bForceNoneRect); if(m_hrgn) { SetWindowPos(m_hWnd,0,0,0,m_width,m_height,SWP_NOMOVE | SWP_NOZORDER); if(SetWindowRgn(m_hWnd,m_hrgn,TRUE)) return m_hrgn; } return NULL; } //动画GIF用,绘制背景 void RingDIB::MakeBkg() { LPANIGIFPIC mark,save; COLORREF *lpmb,*lpl,*lpmbb,*lplb; int i,j,r,b,x,y; if(!m_aniGifPic) return; save = m_aniGifPic->next; mark = m_aniGifPic; while(save != mark && save) { //求剪裁矩形 x = save->x + save->width; y = save->y + save->height; r = x; b = y; lpmb = lpmbb = m_Bits + (m_height - y) * m_width + save->x; lpl = lplb = save->curr; for(j=save->y;j<b;j++) { for(i=save->x;i<r;i++) { if(save->keycolor==0xffffffff || *lpl != save->keycolor) *lpmb = *lpl; lpmb++;lpl++; } lplb += save->width;lpmbb += m_width; lpl = lplb; lpmb = lpmbb; } save = save->next; } } BOOL RingDIB::SetAniGifFilter(ANIFILTER_FUNC func) { GetLocalGifInfo(); if(m_lGifInfo) { m_lGifInfo->funcFilter = func; return TRUE; } else return FALSE; } LPANIGIFPIC RingDIB::AddAniGifPic(LPANIGIFPIC prev,BYTE docase,WORD delay,BOOL bTrans) { LPANIGIFPIC temp; temp = (LPANIGIFPIC)New(sizeof(ANIGIFPIC)); if(temp) { if(m_aniGifPic == NULL) m_aniGifPic = temp; temp->next = NULL; temp->curr = NULL; temp->prev = prev; temp->docase=docase; temp->delay=delay; if(bTrans) temp->keycolor=2; else temp->keycolor=0xFFFFFFFF; if(prev) prev->next = temp; } return temp; }